package com.fudan.es.aggs.handler;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram.Bucket;
import org.elasticsearch.search.aggregations.bucket.nested.ReverseNested;
import org.springframework.stereotype.Component;

import com.fudan.es.Aggs;
import com.fudan.es.aggs.ConstString;
import com.fudan.es.aggs.handler.base.AggsHandler;
import com.fudan.es.entity.DimensionPack;
import com.fudan.es.entity.FieldMeta;
import com.fudan.es.entity.MetricPack;
@Component
public class DateHandler extends AggsHandler{

	@Override
	public AggregationBuilder handle(DimensionPack dimension) {
		FieldMeta field = dimension.getField();
		if(field == null) {
			throw new RuntimeException(NO_FIELD);
		}
		if(!field.getAggregatable()) {
			throw new RuntimeException(FIELD_NOT_AGGREGATABLE);
		}
		if(field.getInNested()) {
			return Aggs.date(field, new DateHistogramInterval(dimension.getInterval())).subAggregation(Aggs.reverse("root"));			
		}else {
			return Aggs.date(field, new DateHistogramInterval(dimension.getInterval()));
		}
	}

	@Override
	public AggregationBuilder build(MetricPack metric) {
		FieldMeta field = metric.getField();
		return Aggs.date(field, new DateHistogramInterval(metric.getInterval()));
	}

	@Override
	public Map<String, Object> handle(Map<String, Object> map, Aggregations aggregations, MetricPack metricPack) {
		if(aggregations == null) return map;
		Integer id = metricPack.getField().getId();
		Histogram terms = aggregations.get(getAggregationName(metricPack));
		List<? extends Bucket> buckets = terms.getBuckets();
		map.put(id.toString(),new HashMap<String, Object>());
		for (Bucket bucket : buckets) {
			Map<String,Object> target = (Map<String, Object>) map.get(id.toString());
			Map<String,Object> atom = new HashMap<>();
			//atom.put(DEFAULT_DOC, bucket.getDocCount());
			FieldMeta grainDef = metricPack.getGrain();
			if(grainDef != null) {
				ReverseNested reverse = bucket.getAggregations().get(ConstString.GRAIN_TAG+"$"+grainDef.getName());
				long grainDoc = reverse.getDocCount();
				atom.put(DEFAULT_DOC, grainDoc);
			}else {
				if(metricPack.getField().getInNested()) {
					ReverseNested reverse = bucket.getAggregations().get("root");
					long grainDoc = reverse.getDocCount();
					atom.put(DEFAULT_DOC, grainDoc);					
				}else {
					atom.put(DEFAULT_DOC, bucket.getDocCount());
				}
			}
			target.put(bucket.getKeyAsString(), atom);

			responseParser.extract(atom,bucket.getAggregations(),metricPack.getMetric(),metricPack.getField().getNestedPath());
		}
		return (Map<String, Object>) map.get(id.toString());
	}

}
